package model

import (
	"database/sql"
	"github.com/gomodule/redigo/redis"
	"strconv"
	"time"
	"tizhi_front/nspel"
)

type Student struct {
	Id               int64           `gorm:"AUTO_INCREMENT;primary_key;column:id"`
	CountryId        int64           `gorm:"column:country_id"`
	ProvinceId       int64           `gorm:"column:province_id"`
	CityId           int64           `gorm:"column:city_id"`
	AreaId           int64           `gorm:"column:area_id"`
	ExperimentAreaId int64           `gorm:"column:experiment_area_id"`
	SchoolId         int64           `gorm:"column:school_id"`
	Name             string          `gorm:"column:name"`
	NickName         string          `gorm:"column:nick_name"`
	PicUrl           string          `gorm:"column:pic_url"`
	SchoolRollId     string          `gorm:"column:school_roll_id"`
	CurrentGrade     string          `gorm:"column:current_grade"`
	CurrentClass     string          `gorm:"column:current_class"`
	Sex              byte            `gorm:"column:sex"`
	Birthday         time.Time       `gorm:"column:birthday"`
	IdentityId       sql.NullString  `gorm:"column:identity_id"`
	Height           sql.NullFloat64 `gorm:"column:height"`
	Weight           sql.NullFloat64 `gorm:"column:weight"`
	Nation           string          `gorm:"column:nation"`
	Phone            sql.NullString  `gorm:"column:phone"`
	Address          sql.NullString  `gorm:"column:address"`
	Password         sql.NullString  `gorm:"column:password"`
	WechatOpenId     sql.NullString  `gorm:"column:wechat_openid"`
	QqOpenId         sql.NullString  `gorm:"column:qq_openid"`
	StudentId        string          `gorm:"column:student_id"`
	Score            float64         `gorm:"column:score"`
	CreatedAt        time.Time       `gorm:"column:created_at"`
	UpdatedAt        time.Time       `gorm:"column:updated_at"`
}

// student0 id 姓名 身份证
// student1 id 姓名 学籍号
// student2 id 学籍号 密码
// student3 id 手机 密码
// student4 学校id 城市id 实验区id 学籍号 姓名 头像 昵称 手机 性别 生日 年级 班级 身高 体重
//*student5 头像 昵称 性别 生日 身高 体重
//*student6 密码
// student7 手机 学籍号
// student8 id
// student9 性别 年级

type Student0 struct {
	Id         int64  `gorm:"AUTO_INCREMENT;primary_key;column:id"`
	Name       string `gorm:"column:name"`
	IdentityId string `gorm:"column:identity_id"`
}

func (*Student0) TableName() string {
	return "student"
}

func (s *Student0) SelectByIdentityId(identityId string) (err error) {
	key := "student0.identity_id:" + identityId
	err = nspel.RedisGetGob(key, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Select([]string{"id", "name", "identity_id"}).Where("identity_id = ?", identityId).First(s).Error; err != nil {
		return
	}
	nspel.RedisSetGob(key, s)
	return
}

func (s *Student0) SelectBySchoolRollId(schoolRollId string) (err error) {
	key := "student0.school_roll_id:" + schoolRollId
	err = nspel.RedisGetGob(key, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Select([]string{"id", "name", "identity_id"}).Where("school_roll_id = ?", schoolRollId).First(s).Error; err != nil {
		return
	}
	nspel.RedisSetGob(key, s)
	return
}

type Student1 struct {
	Id           int64  `gorm:"AUTO_INCREMENT;primary_key;column:id"`
	Name         string `gorm:"column:name"`
	SchoolRollId string `gorm:"column:school_roll_id"`
}

func (*Student1) TableName() string {
	return "student"
}

func (s *Student1) SelectBySchoolRollId(schoolRollId string) (err error) {
	key := "student1.school_roll_id:" + schoolRollId
	err = nspel.RedisGetGob(key, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Select([]string{"id", "name", "school_roll_id"}).Where("school_roll_id = ?", schoolRollId).First(s).Error; err != nil {
		return
	}
	nspel.RedisSetGob(key, s)
	return
}

type Student2 struct {
	Id           int64  `gorm:"AUTO_INCREMENT;primary_key;column:id"`
	SchoolRollId string `gorm:"column:school_roll_id"`
	Password     string `gorm:"column:password"`
}

func (*Student2) TableName() string {
	return "student"
}

func (s *Student2) SelectBySchoolRollId(schoolRollId string) (err error) {
	key := "student2.school_roll_id:" + schoolRollId
	err = nspel.RedisGetGob(key, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Select([]string{"id", "school_roll_id", "password"}).Where("school_roll_id = ?", schoolRollId).First(s).Error; err != nil {
		return
	}
	nspel.RedisSetGob(key, s)
	return
}

type Student3 struct {
	Id       int64  `gorm:"AUTO_INCREMENT;primary_key;column:id"`
	Phone    string `gorm:"column:phone"`
	Password string `gorm:"column:password"`
}

func (*Student3) TableName() string {
	return "student"
}

func (s *Student3) SelectByPhone(phone string) (err error) {
	key := "student3.phone:" + phone
	err = nspel.RedisGetGob(key, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Select([]string{"id", "phone", "password"}).Where("phone = ?", phone).First(s).Error; err != nil {
		return
	}
	nspel.RedisSetGob(key, s)
	return
}

type Student4 struct {
	SchoolId         int64     `gorm:"column:school_id"`
	CityId           int64     `gorm:"column:city_id"`
	ExperimentAreaId int64     `gorm:"column:experiment_area_id"`
	SchoolRollId     string    `gorm:"column:school_roll_id"`
	Name             string    `gorm:"column:name"`
	PicUrl           string    `gorm:"column:pic_url"`
	NickName         string    `gorm:"column:nick_name"`
	Phone            string    `gorm:"column:phone"`
	Sex              byte      `gorm:"column:sex"`
	Birthday         time.Time `gorm:"column:birthday"`
	CurrentGrade     string    `gorm:"column:current_grade"`
	CurrentClass     string    `gorm:"column:current_class"`
	Height           float64   `gorm:"column:height"`
	Weight           float64   `gorm:"column:weight"`
}

func (*Student4) TableName() string {
	return "student"
}

func (s *Student4) SelectById(id int64) (err error) {
	key := "student4.id:" + strconv.FormatInt(id, 10)
	err = nspel.RedisGetGob(key, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Select([]string{"school_id", "city_id", "experiment_area_id", "school_roll_id", "name", "pic_url", "nick_name", "phone", "sex", "birthday", "current_grade", "current_class", "height", "weight"}).Where("id = ?", id).First(s).Error; err != nil {
		return
	}
	nspel.RedisSetGob(key, s)
	return
}

type StudentE struct{}

func (*StudentE) TableName() string {
	return "student"
}

func (*StudentE) SelectCountBySchoolIdCurrentClassScoreGreaterEqual(schoolId int64, currentClass string, score float64) (count int64, err error) {
	key := "student.school_id:" + strconv.FormatInt(schoolId, 10) + ".current_class:" + currentClass + ".score:>=" + strconv.FormatFloat(score, 'f', -1, 64) + ".count"
	err = nspel.RedisGetInt64(key, &count)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Table("student").Where("school_id = ?", schoolId).Where("current_class = ?", currentClass).Where("score >= ?", score).Count(&count).Error; err != nil {
		return
	}
	nspel.RedisSetInt64(key, count)
	return
}

func (*StudentE) SelectCountByExperimentAreaIdScoreGreaterEqual(experimentAreaId int64, score float64) (count int64, err error) {
	key := "student5.experiment_area_id:" + strconv.FormatInt(experimentAreaId, 10) + ".score:>=" + strconv.FormatFloat(score, 'f', -1, 64) + ".count"
	err = nspel.RedisGetInt64(key, &count)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Table("student").Where("experiment_area_id = ?", experimentAreaId).Where("score >= ?", score).Count(&count).Error; err != nil {
		return
	}
	nspel.RedisSetInt64(key, count)
	return
}

func (*StudentE) SelectCountByCityIdScoreGreaterEqual(cityId int64, score float64) (count int64, err error) {
	key := "student5.city_id:" + strconv.FormatInt(cityId, 10) + ".score:>=" + strconv.FormatFloat(score, 'f', -1, 64) + ".count"
	err = nspel.RedisGetInt64(key, &count)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Table("student").Where("city_id = ?", cityId).Where("score >= ?", score).Count(&count).Error; err != nil {
		return
	}
	nspel.RedisSetInt64(key, count)
	return
}

func (*StudentE) SelectCountBySchoolIdCurrentClass(schoolId int64, currentClass string) (count int64, err error) {
	key := "student.school_id:" + strconv.FormatInt(schoolId, 10) + ".current_class:" + currentClass + ".count"
	err = nspel.RedisGetInt64(key, &count)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Table("student").Where("school_id = ?", schoolId).Where("current_class = ?", currentClass).Count(&count).Error; err != nil {
		return
	}
	nspel.RedisSetInt64(key, count)
	return
}

func (*StudentE) SelectCountByExperimentAreaId(experimentAreaId int64) (count int64, err error) {
	key := "student5.experiment_area_id:" + strconv.FormatInt(experimentAreaId, 10) + ".count"
	err = nspel.RedisGetInt64(key, &count)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Table("student").Where("experiment_area_id = ?", experimentAreaId).Count(&count).Error; err != nil {
		return
	}
	nspel.RedisSetInt64(key, count)
	return
}

func (*StudentE) SelectCountByCityId(cityId int64) (count int64, err error) {
	key := "student5.city_id:" + strconv.FormatInt(cityId, 10) + ".count"
	err = nspel.RedisGetInt64(key, &count)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Table("student").Where("city_id = ?", cityId).Count(&count).Error; err != nil {
		return
	}
	nspel.RedisSetInt64(key, count)
	return
}

func (s *StudentE) UpdatePhoneById(id int64, phone string) (err error) {
	student := Student7{}
	err = student.SelectById(id)
	if err != nil {
		return
	}
	err = nspel.GetOrm().Table(s.TableName()).Where("id = ?", id).Update("phone", phone).Error
	if err != nil {
		return
	}
	_ = nspel.RedisKeysDelete("student3.phone:"+student.Phone, "student4.id:"+strconv.FormatInt(id, 10), "student7.id:"+strconv.FormatInt(id, 10))
	return
}

func (s *StudentE) UpdatePicUrlById(id int64, picUrl string) (err error) {
	err = nspel.GetOrm().Table(s.TableName()).Where("id = ?", id).Update("pic_url", picUrl).Error
	if err != nil {
		return
	}
	_ = nspel.RedisKeysDelete("student4.id:"+strconv.FormatInt(id, 10), "student7.id:"+strconv.FormatInt(id, 10))
	return
}

type Student5 struct {
	PicUrl   string    `gorm:"column:pic_url"`
	NickName string    `gorm:"column:nick_name"`
	Sex      byte      `gorm:"column:sex"`
	Birthday time.Time `gorm:"column:birthday"`
	Height   float64   `gorm:"column:height"`
	Weight   float64   `gorm:"column:weight"`
}

func (*Student5) TableName() string {
	return "student"
}

func (s *Student5) UpdateById(id int64) (err error) {
	if err = nspel.GetOrm().Model(Student5{}).Where("id = ?", id).Update(s).Error; err != nil {
		return
	}
	_ = nspel.RedisKeysDelete("student4.id:"+strconv.FormatInt(id, 10), "student9.id:"+strconv.FormatInt(id, 10))
	return
}

type Student6 struct {
	Password string `gorm:"column:password"`
}

func (*Student6) TableName() string {
	return "student"
}

func (s *Student6) SelectById(id int64) (err error) {
	key := "student6.id:" + strconv.FormatInt(id, 10)
	err = nspel.RedisGetGob(key, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Select("password").Where("id = ?", id).First(s).Error; err != nil {
		return
	}
	nspel.RedisSetGob(key, s)
	return
}

func (s *Student6) UpdateById(id int64) (err error) {
	if err = nspel.GetOrm().Model(Student6{}).Where("id = ?", id).Update(s).Error; err != nil {
		return
	}
	_ = nspel.RedisKeysDelete("student6.id:" + strconv.FormatInt(id, 10))
	student := Student7{}
	err = student.SelectById(id)
	if err != nil {
		nspel.Error(err)
		return nil
	}
	_ = nspel.RedisKeysDelete("student3.phone:"+student.Phone, "student2.school_roll_id:"+student.SchoolRollId, "student10.school_roll_id:"+student.SchoolRollId)
	return
}

type Student7 struct {
	Phone        string `gorm:"column:phone"`
	SchoolRollId string `gorm:"column:school_roll_id"`
}

func (*Student7) TableName() string {
	return "student"
}

func (s *Student7) SelectById(id int64) (err error) {
	key := "student7.id:" + strconv.FormatInt(id, 10)
	err = nspel.RedisGetGob(key, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Select([]string{"phone", "school_roll_id"}).Where("id = ?", id).First(s).Error; err != nil {
		return
	}
	nspel.RedisSetGob(key, s)
	return
}

type Student8 struct {
	Id int64 `gorm:"AUTO_INCREMENT;primary_key;column:id"`
}

func (*Student8) TableName() string {
	return "student"
}

func (s *Student8) SelectByPhone(phone string) (err error) {
	key := "student8.phone:" + phone
	err = nspel.RedisGetGob(key, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Select("id").Where("phone = ?", phone).First(s).Error; err != nil {
		return
	}
	nspel.RedisSetGob(key, s)
	return
}

func (s *Student8) SelectByWechatOpenId(wechatOpenId string) (err error) {
	key := "student8.wechat_openid:" + wechatOpenId
	err = nspel.RedisGetGob(key, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Select("id").Where("wechat_openid = ?", wechatOpenId).First(s).Error; err != nil {
		return
	}
	nspel.RedisSetGob(key, s)
	return
}

func (s *Student8) SelectBySchoolRollId(schoolRollId string) (err error) {
	key := "student8.school_roll_id:" + schoolRollId
	err = nspel.RedisGetGob(key, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Select("id").Where("school_roll_id = ?", schoolRollId).First(s).Error; err != nil {
		return
	}
	nspel.RedisSetGob(key, s)
	return
}

type Student9 struct {
	Sex          byte   `gorm:"column:sex"`
	CurrentGrade string `gorm:"column:current_grade"`
}

func (*Student9) TableName() string {
	return "student"
}

func (s *Student9) SelectById(id int64) (err error) {
	key := "student9.id:" + strconv.FormatInt(id, 10)
	err = nspel.RedisGetGob(key, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Select([]string{"sex", "current_grade"}).Where("id = ?", id).First(s).Error; err != nil {
		return
	}
	nspel.RedisSetGob(key, s)
	return
}

type Student10 struct {
	Password     string `gorm:"column:password"`
	WechatOpenId string `gorm:"column:wechat_openid"`
}

func (*Student10) TableName() string {
	return "student"
}

func (s *Student10) SelectBySchoolRollId(schoolRollId string) (err error) {
	key := "student10.school_roll_id:" + schoolRollId
	err = nspel.RedisGetGob(key, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	} else {
		err = nil
	}
	if err = nspel.GetOrm().Select([]string{"password", "wechat_openid"}).Where("school_roll_id = ?", schoolRollId).First(s).Error; err != nil {
		return
	}
	nspel.RedisSetGob(key, s)
	return
}

func (s *Student10) UpdateWechatOpenIdBySchoolRollId(schoolRollId string, wechatOpenId string) (err error) {
	if err = nspel.GetOrm().Model(Student10{}).Where("school_roll_id = ?", schoolRollId).Update("wechat_openid", wechatOpenId).Error; err != nil {
		return
	}
	_ = nspel.RedisKeysDelete("student10.school_roll_id:" + schoolRollId)
	return
}
